<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types = 1);

namespace app\common\service\qrcode;

use app\common\model\Order as OrderModel;
use Exception;
use Grafika\Color;
use Grafika\Grafika;
use think\facade\Db;

/**
 * 票据海报
 * Class Order
 * @package app\common\service\qrcode
 */
class Piaoju extends BaseQRcode
{
    // 当前客户端 (默认H5)
    private string $channel;

    // 商品信息
    private OrderModel $order;

    /**
     * 构造方法
     * Order constructor.
     * @param $order
     * @param int|null $userId
     * @param string $channel 二维码渠道(小程序码、h5码)
     */
    public function __construct(OrderModel $order, ?int $userId = null, string $channel = 'H5')
    {
        parent::__construct();
        // 商品信息
        $this->order = $order;

        // 当前客户端
        $this->channel = $channel;
    }

    /**
     * 拼接海报图
     * @return string
     * @throws \cores\exception\BaseException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws Exception
     */
    public function getImage(): string
    {
        // 判断海报图文件存在则直接返回url
        if (file_exists($this->getPosterPath())) {
            // return $this->getPosterUrl();
        }
        // 商城ID
        $storeId = $this->order['store_id'];
        // 商品海报背景图
        $backdrop = __DIR__ . '/resource/piaoju_bg.png';

        // 拼接海报图
        return $this->savePoster($backdrop);
    }

    /**
     * 拼接海报图
     * @param string $backdrop 背景图路径
     * @param string $orderUrl 商品图路径
     * @param string $qrcode 二维码图路径
     * @return string
     * @throws \Exception
     */
    private function savePoster(string $backdrop): string
    {
        // 实例化图像编辑器
        $editor = Grafika::createEditor(['Gd']);
        // 字体文件路径
        $fontPath = Grafika::fontsDir() . '/' . 'st-heiti-light.ttc';
        // 打开海报背景图
        $editor->open($backdropImage, $backdrop);

        // 开票日期
        $date     = Date('Y-m-d');
        $fontSize = 16;
        // 写入开票日期
        $editor->text($backdropImage, $date, $fontSize, 125, 112, new Color('#333333'));

        // 订单号

        // 写入订单号
        $editor->text($backdropImage, $this->order['order_no'], $fontSize, 535, 112, new Color('#333333'));

        // 个人
        $contract = Db::name('order_contract')->where('order_id', $this->order['order_id'])->field('real_name')->find();
        if ($contract) {
            $realName = $contract['real_name'];
        } else {
            $realName = $this->order['real_name'];
        }
        $editor->text($backdropImage, $realName, $fontSize, 190, 165, new Color('#333333'), $fontPath);

        // 款项内容

        $goodsName = $this->wrapText($fontSize, 0, $fontPath, $this->order['goods'][0]['goods_name'], 380, 2);
        // 写入商品名称
        $editor->text($backdropImage, $goodsName, $fontSize, 190, 240, new Color('#333333'), $fontPath);

        // 写入收款方式
        $payType = '微信支付';
        $editor->text($backdropImage, $payType, $fontSize, 590, 240, new Color('#333333'), $fontPath);
        // 金额大写

        $money = $this->num_to_cn_capital($this->order['total_price']);

        $editor->text($backdropImage, $money, $fontSize, 125, 320, new Color('#333333'), $fontPath);

        // 金额

        $editor->text($backdropImage, $this->order['total_price'], $fontSize, 520, 320, new Color('#333333'), $fontPath);

        // 保存图片
        $editor->save($backdropImage, $this->getPosterPath());
        return $this->getPosterUrl();
    }

    /**
     *数字金额转换成中文大写金额的函数
     *String Int $num 要转换的小写数字或小写字符串
     *return 大写字母
     *小数位为两位
     **/

    public function num_to_cn_capital($num)
    {
        $units = '仟 佰 拾 亿 仟 佰 拾 万 仟 佰 拾 元 角 分';
        $chars = '零 壹 贰 叁 肆 伍 陆 柒 捌 玖';
        $units=explode(' ',$units);
        $chars=explode(' ',$chars);

        //$num = round($num, 2);
        $num     = sprintf("%01.2f", $num);
        $nums    = explode('.', $num);

        $intPart = $nums[0];
        $decPart = $nums[1];
        $intLen  = strlen($intPart);
        $ret     = '';

        for ($k = 0; $k < $intLen; $k++) {
            $ret .= $chars[$intPart[$k]] . $units[12 - $intLen + $k];
        }



        $ret = str_replace('零仟', '零', $ret);
        $ret = str_replace('零佰', '零', $ret);
        $ret = str_replace('零拾', '零', $ret);
        $ret = str_replace('零亿', '亿', $ret);
        $ret = str_replace('亿万', '亿', $ret);
        $ret = str_replace('零万', '万', $ret);
        $ret = str_replace('零元', '元', $ret);
        $ret = preg_replace('/零+/', '零', $ret);
        $ret = preg_replace('/零+元/', '元', $ret);
        $ret = preg_replace('/零+角/', '角', $ret);
        $ret = preg_replace('/零+分/', '分', $ret);
        if (empty($ret)) {
            $ret = '零元整';
            return $ret;
        }

      
        return $ret . '整';
    }

    /**
     * 处理文字超出长度自动换行
     * @param integer $fontsize 字体大小
     * @param integer $angle 角度
     * @param string $fontface 字体名称
     * @param string $string 字符串
     * @param integer $width 预设宽度
     * @param int|null $maxLine 最多行数
     * @return string
     */
    private function wrapText(int $fontsize, int $angle, string $fontface, string $string, int $width, int $maxLine = null): string
    {
        // 这几个变量分别是 字体大小, 角度, 字体名称, 字符串, 预设宽度
        $content = "";
        // 将字符串拆分成一个个单字 保存到数组 letter 中
        $letter = [];
        for ($i = 0; $i < mb_strlen($string, 'UTF-8'); $i++) {
            $letter[] = mb_substr($string, $i, 1, 'UTF-8');
        }
        $line_count = 0;
        foreach ($letter as $l) {
            $testbox = imagettfbbox($fontsize, $angle, $fontface, $content . ' ' . $l);
            // 判断拼接后的字符串是否超过预设的宽度
            if (($testbox[2] > $width) && ($content !== "")) {
                $line_count++;
                if ($maxLine && $line_count >= $maxLine) {
                    $content = mb_substr($content, 0, -1, 'UTF-8') . "...";
                    break;
                }
                $content .= "\n";
            }
            $content .= $l;
        }
        return $content;
    }

    /**
     * 海报图文件路径
     * @return string
     */
    private function getPosterPath(): string
    {
        // 保存路径
        $tempPath = web_path() . "piaoju/{$this->order['store_id']}/";
        ! is_dir($tempPath) && mkdir($tempPath, 0755, true);
        return $tempPath . $this->getPosterName();
    }

    /**
     * 海报图文件名称
     * @return string
     */
    private function getPosterName(): string
    {
        return 'piaoju_' . $this->order['order_id'] . '.png';
    }

    /**
     * 海报图url
     * @return string
     */
    private function getPosterUrl(): string
    {
        return 'piaoju/' . $this->order['store_id'] . '/' . $this->getPosterName() . '?t=' . time();
    }
}
